package whf.framework.xml;

import java.io.FileOutputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;

import whf.framework.datasource.DataRow;
import whf.framework.datasource.DataSource;
import whf.framework.datasource.impl.CollectionDataSource;
import whf.framework.entity.Entity;
import whf.framework.entity.TreeNode;
import whf.framework.entity.decorator.EntityWrapper;
import whf.framework.entity.decorator.WrapperFactory;
import whf.framework.ext.entity.DictItem;
import whf.framework.meta.Meta;
import whf.framework.meta.MetaFactory;
import whf.framework.security.entity.Permission;
import whf.framework.util.BeanUtils;
import whf.framework.util.StringUtils;
import whf.framework.util.Utils;

/**
 * @author wanghaifeng
 *
 */
@SuppressWarnings("unchecked")
public class DictXmlBuilder {
	
	/**
	 * 创建字典项节点
	 * @modify wanghaifeng Aug 28, 2006 11:18:07 PM
	 * @param zdzl
	 * @param zdzlmc
	 * @param items
	 * @return
	 */
	private static Element createElement(String zdzl, String zdzlmc, List items) {
		Element ditems = new Element("ditems");
		ditems.setAttribute("k", zdzl);
		ditems.setAttribute("n", zdzlmc);
		for (Object itemInfo:items) {
			ValueObject vo = (ValueObject)itemInfo;
			String code = vo.value;
			String name = vo.text;
			String p = vo.other;
			Element item = new Element("i");
			item.setAttribute("c", code);
			item.setAttribute("d", name == null? "" : name.trim());
			item.setAttribute("p", p);
			ditems.addContent(item);
		}
		return ditems;
	}
	
	/**
	 * 构建文档对象
	 * @modify wanghaifeng Aug 28, 2006 11:18:39 PM
	 * @param dataSource
	 * @param boClass
	 * @return
	 */
	public static <T extends DataRow> Document buildDocument(DataSource<T> dataSource, Collection<String[]> first, Class boClass, String valueProperty, String textProperty){
		Element root = new Element("dict");
		if(dataSource != null && boClass != null ){
			Meta meta = MetaFactory.findByModelClass(boClass);
			List<ValueObject> list = Utils.newArrayList();
			if(first != null){
				for(String[] ss: first){
					list.add(new ValueObject(ss));
				}
			}
			for(Iterator<T> rows = dataSource.iterator(); rows.hasNext(); ){
				DataRow row = rows.next();
				String value = BeanUtils.getStringProperty(row, valueProperty);
				String text = BeanUtils.getStringProperty(row, textProperty);
				if(row instanceof TreeNode){
					TreeNode item = (TreeNode)row;
					TreeNode parentItem = item.getParent();
					while(parentItem != null){
						text = parentItem.getName()+" / "+text;
						parentItem = parentItem.getParent();
					}
				} else if(row instanceof Permission){
					text = ((Permission)row).getTarget()+"-"+text;
				} else if(WrapperFactory.hasWrapperClass(row.getClass()) && false){
					EntityWrapper wrapperObject = WrapperFactory.getWrapper((Entity)row);
					if(wrapperObject != null){
						text = wrapperObject.getName();
					}
				}
				if(value == null) value = "";
				if(text == null) text = "";
				String[] ss = new String[]{value, text,""};
				list.add(new ValueObject(ss));
			}
			if(!StringUtils.equalsIgnoreCase("code", valueProperty))
				Collections.sort(list);
			root.addContent(createElement(boClass.getName(), meta.getName() == null? boClass.getSimpleName(): meta.getName().trim(), list));
		}
		return new Document(root);
	}
	
	public static <T extends DataRow> Document buildDocument(DataSource<T> dataSource, Class entityClass){
		if(entityClass == DictItem.class){
			return buildDocument(dataSource, null, entityClass, "code", "name");
		} else {
			return buildDocument(dataSource, null, entityClass, "id", "name");
		}
	}
	
	/**
	 * 系统数据类型
	 * @modify wanghaifeng Aug 28, 2006 11:40:47 PM
	 * @return
	 */
	public static Document buildDataTypeDocument(){
		List<String[]> list = Utils.newArrayList();
//		list.add(new String[]{"-1", Messages.getString("datatype.int"),""});
//		list.add(new String[]{"-2", Messages.getString("datatype.double"),""});
//		list.add(new String[]{"-3", Messages.getString("datatype.date"),""});
//		list.add(new String[]{"-4", Messages.getString("datatype.datetime"),""});
		List<whf.framework.meta.entity.Object> objects = Utils.newArrayList();
		try{
			objects = whf.framework.meta.service.ObjectServiceImp.getObjectService().findAll();
		}catch(Exception e){
			//
		}
		return buildDocument(new CollectionDataSource<whf.framework.meta.entity.Object>(objects), list, whf.framework.meta.entity.Object.class, "id", "name");
	}
	
	public static Document getEmptyDocument(){
		return buildDocument(null, null);
	}
	
	static class ValueObject implements Comparable{
		private String value;
		private String text;
		private String other;
		
		public ValueObject(String value, String text, String other){
			this.value = value;
			this.text = text;
			this.other = other;
		}
		
		public ValueObject(String[] arr){
			this.value = arr[0];
			this.text = arr[1];
			if(arr.length > 2){
				this.other = arr[2];
			}
		}

		/* (non-Javadoc)
		 * @see java.lang.Comparable#compareTo(T)
		 */
		public int compareTo(Object o) {
			ValueObject vo = (ValueObject)o;
			return StringUtils.compare(this.text, vo.text);
		}
	}
	
	public static void main(String[] args) throws Exception{
		Document doc = buildDataTypeDocument();
		XMLOutputter out = new XMLOutputter();
		out.output(doc, new FileOutputStream("e:\\1.xml"));
	}
}
